home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Graphics / Viewers / VideoStreamV1.0 / Source / aviDecodeSrc / xanim_avi.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-12  |  24.7 KB  |  1,074 lines

  1.  
  2. /*
  3.  * xanim.h
  4.  *
  5.  * Copyright (C) 1990,1991,1992,1993 by Mark Podlipec. 
  6.  * All rights reserved.
  7.  *
  8.  * This software may be freely copied, modified and redistributed
  9.  * without fee provided that this copyright notice is preserved 
  10.  * intact on all copies and modified copies.
  11.  * 
  12.  * There is no warranty or other guarantee of fitness of this software.
  13.  * It is provided solely "as is". The author(s) disclaim(s) all
  14.  * responsibility and liability with respect to this software's usage
  15.  * or its effect upon hardware or computer systems.
  16.  *
  17.  */
  18.  
  19. /** WAR: Wildly hacked to stream AVI RGB data to stdout, 7/2/94 **/
  20.  
  21. /** WAR: global to buffer one frame of RGB interleaved data **/
  22. unsigned char *frameData = (unsigned char *) 0;
  23.  
  24.  
  25. #include "xanim_avi.h"
  26.  
  27. XA_ACTION *ACT_Get_Action(anim_hdr,type)
  28. XA_ANIM_HDR *anim_hdr;
  29. LONG type;
  30. {
  31.   XA_ACTION *act;
  32.  
  33.   act = (XA_ACTION *)malloc(sizeof(XA_ACTION));
  34.   if (act == 0) TheEnd1("ACT_Get_Action: malloc err\n");
  35.  
  36.   act->type = type;
  37.   act->cmap_rev = 0;
  38.   act->data = 0;
  39.   act->chdr = 0;
  40.   act->h_cmap = 0;
  41.   act->map = 0;
  42.   act->next_same_chdr = 0;
  43.  
  44.   act->next = anim_hdr->acts;  /* insert at front of list */
  45.   anim_hdr->acts = act;
  46.   return(act);
  47. }
  48.  
  49.  
  50.  
  51. XA_CHDR *ACT_Get_CHDR(rev,csize,coff,msize,moff,cmap_flag,map_flag)
  52. ULONG rev,csize,coff,msize,moff;
  53. ULONG cmap_flag,map_flag;
  54. {
  55.   XA_CHDR *chdr;
  56.  
  57.   chdr = (XA_CHDR *)malloc(sizeof(XA_CHDR));
  58.   if (chdr == 0) TheEnd1("ACT_Get_CHDR: malloc err\n");
  59.  
  60.   chdr->rev    = rev;
  61.   chdr->csize  = csize;
  62.   chdr->coff   = coff;
  63.   chdr->msize  = msize;
  64.   chdr->moff   = moff;
  65.   chdr->next   = 0;
  66.   chdr->acts   = 0;
  67.   chdr->new_chdr = 0;
  68.  
  69.   if ( (csize) && (cmap_flag) )
  70.   {
  71.     chdr->cmap = (ColorReg *)malloc(csize * sizeof(ColorReg));
  72.     if (chdr->cmap == 0) TheEnd1("ACT_Get_CHDR: cmap malloc err\n");
  73.   }
  74.   else
  75.   {
  76.     chdr->cmap = 0;
  77.     if ( (csize==0) && (cmap_flag) )
  78.      fprintf(stderr,"ACT_Get_CHDR: csize 0 err\n");
  79.   }
  80.   if ( (msize) && (map_flag) )
  81.   {
  82.     chdr->map = (ULONG *)malloc(msize * sizeof(ULONG));
  83.     if (chdr->map == 0) TheEnd1("ACT_Get_CHDR: map malloc err\n");
  84.   }
  85.   else
  86.   {
  87.     chdr->map = 0;
  88.     if ( (msize==0) && (map_flag) )
  89.      fprintf(stderr,"ACT_Get_CHDR: msize 0 err\n");
  90.   }
  91.  
  92.   return(chdr);
  93. }
  94.  
  95.  
  96.  
  97.  
  98.  
  99.  
  100. XA_CHDR *ACT_Get_CMAP(new_map,csize,coff,msize,moff,rbits,gbits,bbits)
  101. ColorReg *new_map;
  102. ULONG csize,coff,msize,moff;
  103. ULONG rbits,gbits,bbits;
  104. {
  105.   ULONG i;
  106.   XA_CHDR *chdr;
  107.   ULONG rscale,gscale,bscale;
  108.  
  109.   if (   (msize > csize) || (moff < coff) 
  110.       || ( (msize+moff) > (csize+coff) )  )
  111.     TheEnd1("ACT_Get_CMAP: map not in cmap err\n");
  112.  
  113.   chdr = ACT_Get_CHDR(0,csize,coff,msize,moff,TRUE,TRUE);
  114.  
  115.   rscale = 256;
  116.   gscale = 256;
  117.   bscale = 256;
  118.  
  119.   for(i = 0; i < csize; i++)
  120.   {
  121.     chdr->cmap[i].red   = ((rscale * new_map[i].red  ) >> 8);
  122.     chdr->cmap[i].green = ((gscale * new_map[i].green) >> 8);
  123.     chdr->cmap[i].blue  = ((bscale * new_map[i].blue ) >> 8);
  124.   }
  125.   rscale *= 11;
  126.   gscale *= 16;
  127.   bscale *=  5;
  128.   for(i = 0; i < csize; i++)
  129.   {
  130.     register ULONG d = ( (   rscale * new_map[i].red
  131.                + gscale * new_map[i].green
  132.                + bscale * new_map[i].blue) >> 13 );
  133.     chdr->cmap[i].gray = d ;
  134.   }
  135.   for(i = 0; i < csize; i++) 
  136.     chdr->map[i] = i + moff;
  137.   return(chdr);
  138. }
  139.  
  140.  
  141. void TheEnd1(char *message) {
  142.     fprintf(stderr, message);
  143.     exit(-1);
  144. }
  145.  
  146.  
  147. /* Routine to read a big endian long word. */
  148. ULONG UTIL_Get_MSB_Long(fp)
  149.     FILE *fp;
  150. {
  151.     ULONG ret;
  152.  
  153.     ret = fgetc(fp) << 24;
  154.     ret |= fgetc(fp) << 16;
  155.     ret |= fgetc(fp) << 8;
  156.     ret |= fgetc(fp);
  157.     return ret;
  158. }
  159.  
  160.  
  161.  
  162.  
  163. /* Routine to read a little endian long word. */
  164. ULONG UTIL_Get_LSB_Long(fp)
  165.     FILE *fp;
  166. {
  167.     ULONG ret;
  168.  
  169.     ret = fgetc(fp);
  170.     ret |= fgetc(fp) << 8;
  171.     ret |= fgetc(fp) << 16;
  172.     ret |= fgetc(fp) << 24;
  173.     return ret;
  174. }
  175.  
  176.  
  177.  
  178.  
  179. /* Routine to read a little endian half word. */
  180. ULONG UTIL_Get_LSB_Short(fp)
  181.     FILE *fp;
  182. {
  183.     ULONG ret;
  184.  
  185.     ret = fgetc(fp);
  186.     ret |= fgetc(fp) << 8;
  187.     return ret;
  188. }
  189.  
  190.  
  191.  
  192.  
  193. LONG x11_bytes_pixel;
  194.  
  195. #define AVI_MAX_COLORS  256
  196. ColorReg avi_cmap[AVI_MAX_COLORS];
  197. XA_CHDR *avi_chdr;
  198.  
  199. AVI_HDR avi_hdr;
  200. AVI_STREAM_HDR strh_hdr;
  201. VIDS_HDR vids_hdr;
  202.  
  203. ULONG avi_frame_cnt;
  204. ULONG avi_imagex, avi_imagey, avi_imagec;
  205. ULONG avi_compression;
  206.  
  207. /* Several variations of how 8 colors apply to 4x4 block */
  208. /* 0 1
  209.  * 2 3
  210.  */
  211. ULONG avi_quad[16] = {0, 0, 1, 1,
  212.   0, 0, 1, 1,
  213.   2, 2, 3, 3,
  214.   2, 2, 3, 3};
  215.  
  216. AVI_FRAME *avi_frame_start, *avi_frame_cur;
  217.  
  218.  
  219.  
  220.  
  221.  
  222. AVI_FRAME *AVI_Add_Frame(time, act)
  223.     ULONG time;
  224.     XA_ACTION *act;
  225. {
  226.     AVI_FRAME *fframe;
  227.  
  228.     fframe = (AVI_FRAME *) malloc(sizeof(AVI_FRAME));
  229.     fframe->time = time;
  230.     fframe->act = act;
  231.     fframe->next = 0;
  232.  
  233.     if (avi_frame_start == 0)
  234.         avi_frame_start = fframe;
  235.     else
  236.         avi_frame_cur->next = fframe;
  237.  
  238.     avi_frame_cur = fframe;
  239.     avi_frame_cnt++;
  240.     return (fframe);
  241. }
  242.  
  243.  
  244.  
  245.  
  246.  
  247.  
  248. void AVI_Free_Frame_List(fframes)
  249.     AVI_FRAME *fframes;
  250. {
  251.     AVI_FRAME *ftmp;
  252.  
  253.     while (fframes != 0) {
  254.         ftmp = fframes;
  255.         fframes = fframes->next;
  256.         FREE(ftmp, 0x2000);
  257.     }
  258. }
  259.  
  260.  
  261.  
  262.  
  263. LONG Is_AVI_File(filename)
  264.     char *filename;
  265. {
  266.     FILE *fin;
  267.     ULONG data;
  268.  
  269.     if ((fin = fopen(filename, "r")) == 0) {
  270.         fprintf(stderr, "can't open %s\n", filename);
  271.         return(FALSE);
  272.     }
  273.  
  274.     data = UTIL_Get_MSB_Long(fin);    /* read past size */
  275.     fclose(fin);
  276.     if (data == RIFF_RIFF)
  277.         return (TRUE);
  278.     return (FALSE);
  279. }
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286. void AVI_Read_File(fname, anim_hdr)
  287.     char *fname;
  288.     XA_ANIM_HDR *anim_hdr;
  289. {
  290.     FILE *fin;
  291.     LONG i, ret;
  292.     XA_ACTION *act;
  293.     UBYTE *pic;
  294.     ULONG pic_size;
  295.  
  296.     if ((fin = fopen(fname, "r")) == 0) {
  297.         fprintf(stderr, "can't open AVI File %s for reading\n", fname);
  298.         TheEnd1("");
  299.     }
  300.  
  301.     pic = 0;
  302.     avi_chdr = 0;
  303.     avi_frame_cnt = 0;
  304.     avi_frame_start = 0;
  305.     avi_frame_cur = 0;
  306.  
  307.  
  308.     while (!feof(fin)) {
  309.         ULONG d, ck_id, ck_size;
  310.  
  311.         ck_id = UTIL_Get_MSB_Long(fin);
  312.         ck_size = UTIL_Get_LSB_Long(fin);
  313.  
  314.         switch (ck_id) {
  315.         case RIFF_RIFF:
  316.             d = UTIL_Get_MSB_Long(fin);
  317.             break;
  318.         case RIFF_LIST:
  319.             d = UTIL_Get_MSB_Long(fin);
  320.             break;
  321.         case RIFF_avih:
  322.             RIFF_Read_AVIH(fin, ck_size, &avi_hdr);
  323.             break;
  324.         case RIFF_strh:
  325.             RIFF_Read_STRH(fin, ck_size, &strh_hdr);
  326.             break;
  327.         case RIFF_strf:
  328.             switch (strh_hdr.fcc_type) {
  329.             case RIFF_vids:
  330.                 RIFF_Read_VIDS(fin, ck_size, &vids_hdr);
  331.                 if (pic == 0) {
  332.                     pic_size = avi_imagex * avi_imagey;
  333.                     pic = (UBYTE *) malloc(pic_size);
  334.                 }
  335.                 break;
  336.             case RIFF_auds:
  337.                 if (ck_size & 0x01)
  338.                     ck_size++;
  339.                 for (i = 0; i < ck_size; i++)
  340.                     d = getc(fin);
  341.                 break;
  342.             default:
  343.                 fprintf(stderr, "unknown fcc_type at strf, exiting...");
  344.                 exit(-1);
  345.                 break;
  346.             }
  347.             break;
  348.  
  349.         case RIFF_00dc:
  350.             {
  351.                 ACT_DLTA_HDR *dlta_hdr;
  352.                 ULONG d;
  353.  
  354.                 if (ck_size & 0x01)
  355.                     ck_size++;
  356.                 act = ACT_Get_Action(anim_hdr, ACT_DELTA);
  357.                 d = ck_size + (sizeof(ACT_DLTA_HDR));
  358.                 dlta_hdr = (ACT_DLTA_HDR *) malloc(d);
  359.                 act->data = (UBYTE *) dlta_hdr;
  360.                 dlta_hdr->data = (UBYTE *) ((ULONG) dlta_hdr + sizeof(ACT_DLTA_HDR));
  361.                 ret = fread(dlta_hdr->data, ck_size, 1, fin);
  362.                 if (ret != 1)
  363.                     TheEnd1("AVI 00dc: read failed");
  364.                 AVI_Add_Frame(17, act);
  365.                 dlta_hdr->flags = ACT_SNGL_BUF;
  366.                 dlta_hdr->xpos = dlta_hdr->ypos = 0;
  367.                 dlta_hdr->xsize = avi_imagex;
  368.                 dlta_hdr->ysize = avi_imagey;
  369.                 dlta_hdr->special = 0;
  370.                 switch (avi_compression) {
  371.                 case RIFF_CRAM:
  372.                     dlta_hdr->delta = AVI_Decode_CRAM;
  373.                     break;
  374.                 default:
  375.                     fprintf(stderr, "AVI: unsupported comp %lx\n", avi_compression);
  376.                     act->type = ACT_NOP;
  377.                     break;
  378.                 }
  379.                 if (act->type != ACT_NOP) {
  380.                     ULONG xpos, ypos, xsize, ysize, dlta_flag;
  381.  
  382.                     dlta_flag = dlta_hdr->delta(pic, dlta_hdr->data,
  383.                       avi_chdr->map, FALSE, avi_imagex, avi_imagey, 8,
  384.                       &xpos, &ypos, &xsize, &ysize);
  385.                       
  386.     /*** WAR: Write the frame RGB data here***************/
  387.     {
  388.         unsigned char *framePtr=frameData, *picPtr=pic;
  389.         int j;
  390.         for(j=0; j<pic_size; j++) {
  391.             *framePtr++ = avi_cmap[*picPtr].red;
  392.             *framePtr++ = avi_cmap[*picPtr].green;
  393.             *framePtr++ = avi_cmap[*picPtr++].blue;
  394.         }
  395.         fwrite(frameData, 3*pic_size, sizeof(unsigned char), stdout);
  396.         fflush(stdout);
  397.     }
  398.     /******************************************************/
  399.         
  400.     
  401.                     FREE(dlta_hdr, 0x3000);
  402.                     act->data = 0;
  403.                     if (dlta_flag & ACT_DLTA_NOP)
  404.                         act->type = ACT_NOP;
  405.                     } /* end of buffer */
  406.             }
  407.             break;
  408.  
  409.         case RIFF_idx1:
  410.         case RIFF_vedt:
  411.         case RIFF_strd:
  412.         case RIFF_strl:
  413.         case RIFF_CRAM:
  414.         case RIFF_hdrl:
  415.         case RIFF_vids:
  416.         case RIFF_msvc:
  417.         case RIFF_JUNK:
  418.         case RIFF_01wb:
  419.         case RIFF_DISP:
  420.         case RIFF_ISBJ:
  421.             if (ck_size & 0x01)    
  422.                 ck_size++;
  423.             for (i = 0; i < ck_size; i++)
  424.                 d = getc(fin);
  425.             break;
  426.  
  427.         default:
  428.             if (!feof(fin)) {
  429.                 fprintf(stderr, " chunk unknown\n");
  430.                 exit(0);
  431.             }
  432.  
  433.         } /* end of ck_id switch */
  434.     } /* while not exitflag */
  435.  
  436.     if (pic != 0) {
  437.         FREE(pic, 0x3000);
  438.         pic = 0;
  439.     }
  440.     fclose(fin);
  441.  
  442. /********** WAR: don't print info in piped version
  443.     if (FALSE) {     
  444.         fprintf(stderr, "AVI %ldx%ldx%ld frames %ld codec ",
  445.           avi_imagex, avi_imagey, avi_imagec, avi_frame_cnt);
  446.         if (avi_compression == RIFF_CRAM)
  447.             fprintf(stderr, " CRAM 8bit\n");
  448.         else
  449.             fprintf(stderr, " unknown\n");
  450.     }
  451. *************/
  452.     anim_hdr->frame_lst = (XA_FRAME *)
  453.       malloc(sizeof(XA_FRAME) * (avi_frame_cnt + 1));
  454.  
  455.     avi_frame_cur = avi_frame_start;
  456.     i = 0;
  457.     while (avi_frame_cur != 0) {
  458.         if (i > avi_frame_cnt) {
  459.             fprintf(stderr, "AVI_Read_Anim: frame inconsistency %ld %ld\n",
  460.               i, avi_frame_cnt);
  461.             break;
  462.         }
  463.         anim_hdr->frame_lst[i].time = avi_frame_cur->time;
  464.         anim_hdr->frame_lst[i].act = avi_frame_cur->act;
  465.         avi_frame_cur = avi_frame_cur->next;
  466.         i++;
  467.     }
  468.     anim_hdr->imagex = avi_imagex;
  469.     anim_hdr->imagey = avi_imagey;
  470.     anim_hdr->imagec = avi_imagec;
  471.     anim_hdr->imaged = 8;        /* nop */
  472.     anim_hdr->frame_lst[i].time = 0;
  473.     anim_hdr->frame_lst[i].act = 0;
  474.     anim_hdr->loop_frame = 0;
  475.     if (i > 0)
  476.         anim_hdr->last_frame = i - 1;
  477.     else
  478.         i = 0;
  479.     AVI_Free_Frame_List(avi_frame_start);
  480.     
  481.     /****** WAR: free frameData ********************/
  482.     if(frameData) {
  483.         free(frameData);
  484.     }
  485.     /***********************************************/
  486.  
  487. } /* end of file */
  488.  
  489.  
  490.  
  491.  
  492.  
  493. void RIFF_Read_AVIH(fin, size, avi_hdr)
  494.     FILE *fin;
  495.     ULONG size;
  496.     AVI_HDR *avi_hdr;
  497. {
  498.     if (size != 0x38) {
  499.         fprintf(stderr, " size=%ld\n", size);
  500.         TheEnd1("avih: size not 56\n");
  501.     }
  502.  
  503.     avi_hdr->us_frame = UTIL_Get_LSB_Long(fin);
  504.     avi_hdr->max_bps = UTIL_Get_LSB_Long(fin);
  505.     avi_hdr->pad_gran = UTIL_Get_LSB_Long(fin);
  506.     avi_hdr->flags = UTIL_Get_LSB_Long(fin);
  507.     avi_hdr->tot_frames = UTIL_Get_LSB_Long(fin);
  508.     avi_hdr->init_frames = UTIL_Get_LSB_Long(fin);
  509.     avi_hdr->streams = UTIL_Get_LSB_Long(fin);
  510.     avi_hdr->sug_bsize = UTIL_Get_LSB_Long(fin);
  511.     avi_hdr->width = UTIL_Get_LSB_Long(fin);
  512.     avi_hdr->height = UTIL_Get_LSB_Long(fin);
  513.     avi_hdr->scale = UTIL_Get_LSB_Long(fin);
  514.     avi_hdr->rate = UTIL_Get_LSB_Long(fin);
  515.     avi_hdr->start = UTIL_Get_LSB_Long(fin);
  516.     avi_hdr->length = UTIL_Get_LSB_Long(fin);
  517. }
  518.  
  519.  
  520.  
  521.  
  522.  
  523.  
  524. void RIFF_Read_STRH(fin, size, strh_hdr)
  525.     FILE *fin;
  526.     ULONG size;
  527.     AVI_STREAM_HDR *strh_hdr;
  528. {
  529.     ULONG d, tsize;
  530.  
  531.     if (size < 0x24)
  532.         TheEnd1("strh: size is less than 36 \n");
  533.  
  534.     strh_hdr->fcc_type = UTIL_Get_MSB_Long(fin);
  535.     strh_hdr->fcc_handler = UTIL_Get_MSB_Long(fin);
  536.     strh_hdr->flags = UTIL_Get_LSB_Long(fin);
  537.     strh_hdr->priority = UTIL_Get_LSB_Long(fin);
  538.     strh_hdr->init_frames = UTIL_Get_LSB_Long(fin);
  539.     strh_hdr->scale = UTIL_Get_LSB_Long(fin);
  540.     strh_hdr->rate = UTIL_Get_LSB_Long(fin);
  541.     strh_hdr->start = UTIL_Get_LSB_Long(fin);
  542.     strh_hdr->length = UTIL_Get_LSB_Long(fin);
  543.     strh_hdr->sug_bsize = UTIL_Get_LSB_Long(fin);
  544.     strh_hdr->quality = UTIL_Get_LSB_Long(fin);
  545.     strh_hdr->samp_size = UTIL_Get_LSB_Long(fin);
  546.  
  547.     tsize = 48;
  548.     if (size & 0x01)
  549.         size++;
  550.     while (tsize < size) {
  551.         d = getc(fin);
  552.         tsize++;
  553.     }
  554. }
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561.  
  562. void RIFF_Read_VIDS(fin, size, vids_hdr)
  563.     FILE *fin;
  564.     ULONG size;
  565.     VIDS_HDR *vids_hdr;
  566. {
  567.     ULONG d, i, tsize;
  568.  
  569.     vids_hdr->size = UTIL_Get_LSB_Long(fin);
  570.     vids_hdr->width = UTIL_Get_LSB_Long(fin);
  571.     vids_hdr->height = UTIL_Get_LSB_Long(fin);
  572.     vids_hdr->planes = UTIL_Get_LSB_Short(fin);
  573.     vids_hdr->bit_cnt = UTIL_Get_LSB_Short(fin);
  574.     vids_hdr->compression = UTIL_Get_MSB_Long(fin);
  575.     vids_hdr->image_size = UTIL_Get_LSB_Long(fin);
  576.     vids_hdr->xpels_meter = UTIL_Get_LSB_Long(fin);
  577.     vids_hdr->ypels_meter = UTIL_Get_LSB_Long(fin);
  578.     vids_hdr->num_colors = UTIL_Get_LSB_Long(fin);
  579.     vids_hdr->imp_colors = UTIL_Get_LSB_Long(fin);
  580.  
  581.  
  582.     if (vids_hdr->bit_cnt != 8)
  583.         TheEnd1("AVI: bit_cnt not 8 not supported\n");
  584.     if (vids_hdr->num_colors == 0)
  585.         TheEnd1("AVI: num_color=0 not supported\n");
  586.  
  587.     avi_compression = vids_hdr->compression;
  588.     avi_imagex = vids_hdr->width;
  589.     avi_imagey = vids_hdr->height;
  590.     
  591.     /******* WAR: write width and height to stdout, and allocate frameData ************/
  592.     fwrite(&avi_imagex, 1, sizeof(int), stdout);
  593.     fwrite(&avi_imagey, 1, sizeof(int), stdout);
  594.     fflush(stdout);
  595.     frameData = (unsigned char *) malloc(3 * avi_imagex * avi_imagey);
  596.     /***********************************************************************************/
  597.     
  598.     if (vids_hdr->num_colors == 0)
  599.         vids_hdr->num_colors = 256;
  600.     avi_imagec = vids_hdr->num_colors;
  601.  
  602.     for (i = 0; i < vids_hdr->num_colors; i++) {
  603.         avi_cmap[i].blue = (getc(fin)) & 0xff;
  604.         avi_cmap[i].green = (getc(fin)) & 0xff;
  605.         avi_cmap[i].red = (getc(fin)) & 0xff;
  606.         d = getc(fin);            /* pad */
  607.     }
  608.     tsize = vids_hdr->num_colors * 4 + 40;
  609.     if (size & 0x01)
  610.         size++;
  611.     while (tsize < size) {
  612.         d = getc(fin);
  613.         tsize++;
  614.     }
  615.  
  616.     avi_chdr = ACT_Get_CMAP(avi_cmap, avi_imagec, 0, avi_imagec, 0, 8, 8, 8);
  617. }
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626. /* Routine to Decode an AVI CRAM chunk */
  627. ULONG AVI_Decode_CRAM(image, delta, map, map_flag, imagex, imagey, imaged,
  628.   xs, ys, xe, ye, special)
  629.     UBYTE *image;                /* Image Buffer. */
  630.     UBYTE *delta;                /* delta data. */
  631.     ULONG *map;                    /* used if it's going to be remapped. */
  632.     ULONG map_flag;                /* whether or not to use remap_map info. */
  633.     ULONG imagex, imagey;        /* Size of image buffer. */
  634.     ULONG imaged;                /* Depth of Image. (IFF specific) */
  635.     ULONG *xs, *ys;                /* pos of changed area. */
  636.     ULONG *xe, *ye;                /* size of changed area. */
  637.     ULONG special;                /* Special Info. */
  638. {
  639.     ULONG row_dec, exitflag, changed;
  640.     ULONG code0, code1;
  641.     LONG x, y, min_x, max_x, min_y, max_y;
  642.     UBYTE *dptr;
  643.  
  644.     changed = 0;
  645.     max_x = max_y = 0;
  646.     min_x = imagex;
  647.     min_y = imagey;
  648.     dptr = delta;
  649.     row_dec = imagex + 4;
  650.     x = 0;
  651.     y = imagey - 1;
  652.     exitflag = 0;
  653.  
  654.     if (map_flag == TRUE) {
  655.         if (x11_bytes_pixel == 4) {
  656.             while (!exitflag) {
  657.                 code0 = *dptr++;
  658.                 code1 = *dptr++;
  659.                 if ((code1 == 0) && (code0 == 0))
  660.                     exitflag = 1;
  661.                 else {
  662.                     if (y < 0) {
  663.                         exitflag = 1;
  664.                         fprintf(stderr, "AVI: ovr err\n");
  665.                     }
  666.                     if ((code1 >= 0x84) && (code1 <= 0x87)) {    /* skip */
  667.                         ULONG skip = ((code1 - 0x84) << 8) + code0;
  668.  
  669.                         while (skip--) {
  670.                             x += 4;
  671.                             if (x >= imagex) {
  672.                                 x = 0;
  673.                                 y -= 4;
  674.                             }
  675.                         }
  676.                     }
  677.                     else if ((code1 >= 0x81) && (code1 <= 0x83)) {
  678.                         fprintf(stderr, "AVI: unknown code %lx %lx\n", code1, code0);
  679.                     }
  680.                     else {        /* single block encoded */
  681.                         if (code1 >= 0x90) {    /* 8 color quad encoding */
  682.                             ULONG i, mask, pix_bits, clr_A[4], clr_B[4];
  683.                             ULONG *i_ptr = (ULONG *) (image + ((y * imagex + x) << 2));
  684.  
  685.                             clr_B[0] = (ULONG) map[*dptr++];
  686.                             clr_A[0] = (ULONG) map[*dptr++];
  687.                             clr_B[1] = (ULONG) map[*dptr++];
  688.                             clr_A[1] = (ULONG) map[*dptr++];
  689.                             clr_B[2] = (ULONG) map[*dptr++];
  690.                             clr_A[2] = (ULONG) map[*dptr++];
  691.                             clr_B[3] = (ULONG) map[*dptr++];
  692.                             clr_A[3] = (ULONG) map[*dptr++];
  693.                             pix_bits = (code1 << 8) | code0;
  694.                             mask = 0x0001;
  695.                             for (i = 0; i < 16; i++) {
  696.                                 if (mask & pix_bits)
  697.                                     *i_ptr++ = clr_B[avi_quad[i]];
  698.                                 else
  699.                                     *i_ptr++ = clr_A[avi_quad[i]];
  700.                                 mask <<= 1;
  701.                                 if ((i % 4) == 3)
  702.                                     i_ptr -= row_dec;
  703.                             }
  704.                         } /* end of 8 color quad encoding */
  705.                         else if (code1 < 0x80) {    /* 2 color encoding */
  706.                             register ULONG i, mask, pix_bits, clr_A, clr_B;
  707.                             ULONG *i_ptr = (ULONG *) (image + ((y * imagex + x) << 2));
  708.  
  709.                             clr_B = (ULONG) map[*dptr++];
  710.                             clr_A = (ULONG) map[*dptr++];
  711.                             pix_bits = (code1 << 8) | code0;
  712.                             mask = 0x0001;
  713.                             for (i = 0; i < 16; i++) {
  714.                                 if (mask & pix_bits)
  715.                                     *i_ptr++ = clr_B;
  716.                                 else
  717.                                     *i_ptr++ = clr_A;
  718.                                 mask <<= 1;
  719.                                 if ((i % 4) == 3)
  720.                                     i_ptr -= row_dec;
  721.                             }
  722.                         } /* end of 2 color */
  723.                         else {    /* 1 color encoding */
  724.                             ULONG i, clr;
  725.                             ULONG *i_ptr = (ULONG *) (image + ((y * imagex + x) << 2));
  726.  
  727.                             clr = (ULONG) map[code0];
  728.                             for (i = 0; i < 16; i++) {
  729.                                 *i_ptr++ = clr;
  730.                                 if ((i % 4) == 3)
  731.                                     i_ptr -= row_dec;
  732.                             }
  733.                         }
  734.                         if (x < min_x)
  735.                             min_x = x;
  736.                         if (y > max_y)
  737.                             max_y = y;
  738.                         if (x > max_x)
  739.                             max_x = x;
  740.                         if (y < min_y)
  741.                             min_y = y;
  742.                         x += 4;
  743.                         if (x >= imagex) {
  744.                             x = 0;
  745.                             y -= 4;
  746.                         } /* move forward */
  747.                         changed = 1;
  748.                     } /* end of single block */
  749.                 } /* end of not term code */
  750.             } /* end of not while exit */
  751.         } /* end of 4 bytes pixel */
  752.         else if (x11_bytes_pixel == 2) {
  753.             while (!exitflag) {
  754.                 code0 = *dptr++;
  755.                 code1 = *dptr++;
  756.                 if ((code1 == 0) && (code0 == 0))
  757.                     exitflag = 1;
  758.                 else {
  759.                     if (y < 0) {
  760.                         exitflag = 1;
  761.                         fprintf(stderr, "AVI: ovr err\n");
  762.                     }
  763.                     if ((code1 >= 0x84) && (code1 <= 0x87)) {    /* skip */
  764.                         ULONG skip = ((code1 - 0x84) << 8) + code0;
  765.  
  766.                         while (skip--) {
  767.                             x += 4;
  768.                             if (x >= imagex) {
  769.                                 x = 0;
  770.                                 y -= 4;
  771.                             }
  772.                         }
  773.                     }
  774.                     else if ((code1 >= 0x81) && (code1 <= 0x83)) {
  775.                         fprintf(stderr, "AVI: unknown code %lx %lx\n", code1, code0);
  776.                     }
  777.                     else {        /* single block encoded */
  778.                         if (code1 >= 0x90) {    /* 8 color quad encoding */
  779.                             ULONG i, mask, pix_bits;
  780.                             USHORT clr_A[4], clr_B[4];
  781.                             USHORT *i_ptr = (USHORT *) (image + ((y * imagex + x) << 1));
  782.  
  783.                             clr_B[0] = map[*dptr++];
  784.                             clr_A[0] = map[*dptr++];
  785.                             clr_B[1] = map[*dptr++];
  786.                             clr_A[1] = map[*dptr++];
  787.                             clr_B[2] = map[*dptr++];
  788.                             clr_A[2] = map[*dptr++];
  789.                             clr_B[3] = map[*dptr++];
  790.                             clr_A[3] = map[*dptr++];
  791.                             pix_bits = (code1 << 8) | code0;
  792.                             mask = 0x0001;
  793.                             for (i = 0; i < 16; i++) {
  794.                                 if (mask & pix_bits)
  795.                                     *i_ptr++ = (USHORT) clr_B[avi_quad[i]];
  796.                                 else
  797.                                     *i_ptr++ = (USHORT) clr_A[avi_quad[i]];
  798.                                 mask <<= 1;
  799.                                 if ((i % 4) == 3)
  800.                                     i_ptr -= row_dec;
  801.                             }
  802.                         } /* end of 8 color quad encoding */
  803.                         else if (code1 < 0x80) {    /* 2 color encoding */
  804.                             register ULONG i, mask, pix_bits;
  805.                             USHORT clr_A, clr_B;
  806.                             USHORT *i_ptr = (USHORT *) (image + ((y * imagex + x) << 1));
  807.  
  808.                             clr_B = (USHORT) map[*dptr++];
  809.                             clr_A = (USHORT) map[*dptr++];
  810.                             pix_bits = (code1 << 8) | code0;
  811.                             mask = 0x0001;
  812.                             for (i = 0; i < 16; i++) {
  813.                                 if (mask & pix_bits)
  814.                                     *i_ptr++ = clr_B;
  815.                                 else
  816.                                     *i_ptr++ = clr_A;
  817.                                 mask <<= 1;
  818.                                 if ((i % 4) == 3)
  819.                                     i_ptr -= row_dec;
  820.                             }
  821.                         } /* end of 2 color */
  822.                         else {    /* 1 color encoding */
  823.                             ULONG i;
  824.                             USHORT clr;
  825.                             USHORT *i_ptr = (USHORT *) (image + ((y * imagex + x) << 1));
  826.  
  827.                             clr = (USHORT) map[code0];
  828.                             for (i = 0; i < 16; i++) {
  829.                                 *i_ptr++ = clr;
  830.                                 if ((i % 4) == 3)
  831.                                     i_ptr -= row_dec;
  832.                             }
  833.                         }
  834.                         if (x < min_x)
  835.                             min_x = x;
  836.                         if (y > max_y)
  837.                             max_y = y;
  838.                         if (x > max_x)
  839.                             max_x = x;
  840.                         if (y < min_y)
  841.                             min_y = y;
  842.                         x += 4;
  843.                         if (x >= imagex) {
  844.                             x = 0;
  845.                             y -= 4;
  846.                         } /* move forward */
  847.                         changed = 1;
  848.                     } /* end of single block */
  849.                 } /* end of not term code */
  850.             } /* end of not while exit */
  851.         } /* end of 2 bytes pixel */
  852.         else {                    /* (x11_bytes_pixel == 1) */
  853.             while (!exitflag) {
  854.                 code0 = *dptr++;
  855.                 code1 = *dptr++;
  856.                 if ((code1 == 0) && (code0 == 0))
  857.                     exitflag = 1;
  858.                 else {
  859.                     if (y < 0) {
  860.                         exitflag = 1;
  861.                         fprintf(stderr, "AVI: ovr err\n");
  862.                     }
  863.                     if ((code1 >= 0x84) && (code1 <= 0x87)) {    /* skip */
  864.                         ULONG skip = ((code1 - 0x84) << 8) + code0;
  865.  
  866.                         while (skip--) {
  867.                             x += 4;
  868.                             if (x >= imagex) {
  869.                                 x = 0;
  870.                                 y -= 4;
  871.                             }
  872.                         }
  873.                     }
  874.                     else if ((code1 >= 0x81) && (code1 <= 0x83)) {
  875.                         fprintf(stderr, "AVI: unknown code %lx %lx\n", code1, code0);
  876.                     }
  877.                     else {        /* single block encoded */
  878.                         if (code1 >= 0x90) {    /* 8 color quad encoding */
  879.                             ULONG i, mask, pix_bits;
  880.                             UBYTE clr_A[4], clr_B[4];
  881.                             UBYTE *i_ptr = (UBYTE *) (image + y * imagex + x);
  882.  
  883.                             clr_B[0] = (UBYTE) map[*dptr++];
  884.                             clr_A[0] = (UBYTE) map[*dptr++];
  885.                             clr_B[1] = (UBYTE) map[*dptr++];
  886.                             clr_A[1] = (UBYTE) map[*dptr++];
  887.                             clr_B[2] = (UBYTE) map[*dptr++];
  888.                             clr_A[2] = (UBYTE) map[*dptr++];
  889.                             clr_B[3] = (UBYTE) map[*dptr++];
  890.                             clr_A[3] = (UBYTE) map[*dptr++];
  891.                             pix_bits = (code1 << 8) | code0;
  892.                             mask = 0x0001;
  893.                             for (i = 0; i < 16; i++) {
  894.                                 if (mask & pix_bits)
  895.                                     *i_ptr++ = clr_B[avi_quad[i]];
  896.                                 else
  897.                                     *i_ptr++ = clr_A[avi_quad[i]];
  898.                                 mask <<= 1;
  899.                                 if ((i % 4) == 3)
  900.                                     i_ptr -= row_dec;
  901.                             }
  902.                         } /* end of 8 color quad encoding */
  903.                         else if (code1 < 0x80) {    /* 2 color encoding */
  904.                             register ULONG i, mask, pix_bits;
  905.                             UBYTE clr_A, clr_B;
  906.                             UBYTE *i_ptr = (UBYTE *) (image + y * imagex + x);
  907.  
  908.                             clr_B = (UBYTE) map[*dptr++];
  909.                             clr_A = (UBYTE) map[*dptr++];
  910.                             pix_bits = (code1 << 8) | code0;
  911.                             mask = 0x0001;
  912.                             for (i = 0; i < 16; i++) {
  913.                                 if (mask & pix_bits)
  914.                                     *i_ptr++ = clr_B;
  915.                                 else
  916.                                     *i_ptr++ = clr_A;
  917.                                 mask <<= 1;
  918.                                 if ((i % 4) == 3)
  919.                                     i_ptr -= row_dec;
  920.                             }
  921.                         } /* end of 2 color */
  922.                         else {    /* 1 color encoding */
  923.                             ULONG i;
  924.                             UBYTE clr;
  925.                             UBYTE *i_ptr = (UBYTE *) (image + y * imagex + x);
  926.  
  927.                             clr = (UBYTE) map[code0];
  928.                             for (i = 0; i < 16; i++) {
  929.                                 *i_ptr++ = clr;
  930.                                 if ((i % 4) == 3)
  931.                                     i_ptr -= row_dec;
  932.                             }
  933.                         }
  934.                         if (x < min_x)
  935.                             min_x = x;
  936.                         if (y > max_y)
  937.                             max_y = y;
  938.                         if (x > max_x)
  939.                             max_x = x;
  940.                         if (y < min_y)
  941.                             min_y = y;
  942.                         x += 4;
  943.                         if (x >= imagex) {
  944.                             x = 0;
  945.                             y -= 4;
  946.                         } /* move forward */
  947.                         changed = 1;
  948.                     } /* end of single block */
  949.                 } /* end of not term code */
  950.             } /* end of not while exit */
  951.         } /* end of 1 bytes pixel */
  952.     } /* end of map is TRUE */
  953.     else {
  954.         while (!exitflag) {
  955.             code0 = *dptr++;
  956.             code1 = *dptr++;
  957.             if ((code1 == 0) && (code0 == 0))
  958.                 exitflag = 1;
  959.             else {
  960.                 if (y < 0) {
  961.                     exitflag = 1;
  962.                     fprintf(stderr, "AVI: ovr err\n");
  963.                 }
  964.                 if ((code1 >= 0x84) && (code1 <= 0x87)) {    /* skip */
  965.                     ULONG skip = ((code1 - 0x84) << 8) + code0;
  966.  
  967.                     while (skip--) {
  968.                         x += 4;
  969.                         if (x >= imagex) {
  970.                             x = 0;
  971.                             y -= 4;
  972.                         }
  973.                     }
  974.                 }
  975.                 else if ((code1 >= 0x81) && (code1 <= 0x83)) {
  976.                     fprintf(stderr, "AVI: unknown code %lx %lx\n", code1, code0);
  977.                 }
  978.                 else {            /* single block encoded */
  979.                     if (code1 >= 0x90) {    /* 8 color quad encoding */
  980.                         ULONG i, mask, pix_bits, clr_A[4], clr_B[4];
  981.                         UBYTE *i_ptr = (UBYTE *) (image + y * imagex + x);
  982.  
  983.                         clr_B[0] = (UBYTE) * dptr++;
  984.                         clr_A[0] = (UBYTE) * dptr++;
  985.                         clr_B[1] = (UBYTE) * dptr++;
  986.                         clr_A[1] = (UBYTE) * dptr++;
  987.                         clr_B[2] = (UBYTE) * dptr++;
  988.                         clr_A[2] = (UBYTE) * dptr++;
  989.                         clr_B[3] = (UBYTE) * dptr++;
  990.                         clr_A[3] = (UBYTE) * dptr++;
  991.                         pix_bits = (code1 << 8) | code0;
  992.                         mask = 0x0001;
  993.                         for (i = 0; i < 16; i++) {
  994.                             if (mask & pix_bits)
  995.                                 *i_ptr++ = clr_B[avi_quad[i]];
  996.                             else
  997.                                 *i_ptr++ = clr_A[avi_quad[i]];
  998.                             mask <<= 1;
  999.                             if ((i % 4) == 3)
  1000.                                 i_ptr -= row_dec;
  1001.                         }
  1002.                     } /* end of 8 color quad encoding */
  1003.                     else if (code1 < 0x80) {    /* 2 color encoding */
  1004.                         register ULONG i, mask, pix_bits, clr_A, clr_B;
  1005.                         UBYTE *i_ptr = (UBYTE *) (image + y * imagex + x);
  1006.  
  1007.                         clr_B = (UBYTE) * dptr++;
  1008.                         clr_A = (UBYTE) * dptr++;
  1009.                         pix_bits = (code1 << 8) | code0;
  1010.                         mask = 0x0001;
  1011.                         for (i = 0; i < 16; i++) {
  1012.                             if (mask & pix_bits)
  1013.                                 *i_ptr++ = clr_B;
  1014.                             else
  1015.                                 *i_ptr++ = clr_A;
  1016.                             mask <<= 1;
  1017.                             if ((i % 4) == 3)
  1018.                                 i_ptr -= row_dec;
  1019.                         }
  1020.                     } /* end of 2 color */
  1021.                     else {        /* 1 color encoding */
  1022.                         ULONG i, clr;
  1023.                         UBYTE *i_ptr = (UBYTE *) (image + y * imagex + x);
  1024.  
  1025.                         clr = (UBYTE) code0;
  1026.                         for (i = 0; i < 16; i++) {
  1027.                             *i_ptr++ = clr;
  1028.                             if ((i % 4) == 3)
  1029.                                 i_ptr -= row_dec;
  1030.                         }
  1031.                     }
  1032.                     if (x < min_x)
  1033.                         min_x = x;
  1034.                     if (y > max_y)
  1035.                         max_y = y;
  1036.                     if (x > max_x)
  1037.                         max_x = x;
  1038.                     if (y < min_y)
  1039.                         min_y = y;
  1040.                     x += 4;
  1041.                     if (x >= imagex) {
  1042.                         x = 0;
  1043.                         y -= 4;
  1044.                     } /* move forward */
  1045.                     changed = 1;
  1046.                 } /* end of single block */
  1047.             } /* end of not term code */
  1048.         } /* end of not while exit */
  1049.     }
  1050.     if (FALSE) /**WAR: was (xa_optimize_flag == TRUE)  **/ {
  1051.         if (changed) {
  1052.             *xs = min_x;
  1053.             *ys = min_y - 3;
  1054.             *xe = max_x + 4;
  1055.             *ye = max_y + 1;
  1056.         }
  1057.         else {
  1058.             *xs = *ys = *xe = *ye = 0;
  1059.             return (ACT_DLTA_NOP);
  1060.         }
  1061.     }
  1062.     else {
  1063.         *xs = *ys = 0;
  1064.         *xe = imagex;
  1065.         *ye = imagey;
  1066.     }
  1067.     if (map_flag)
  1068.         return (ACT_DLTA_MAPD);
  1069.     else
  1070.         return (ACT_DLTA_NORM);
  1071. }
  1072.  
  1073.  
  1074.